package Main;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Stroke;
import java.awt.TexturePaint;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.LinkedList;
import java.util.concurrent.locks.ReentrantLock;

import javax.imageio.ImageIO;
import javax.swing.JPanel;

import Game_Over.GameOver;
import Greedy_Snake_Map.MMap;
import Greedy_Snake_Map.Map_Type;
import Greedy_Snake_Map.Time;
import Mouse_key_Event.Key;
import chart.IO;
import player.Musics;
import snake.Snake_Point;
import snake.Snake_body;

public class mainPanel extends JPanel implements ActionListener,Runnable
{

	
	private static ReentrantLock game_lock=new ReentrantLock();
	TexturePaint tpapple,tpbanana,tpwaterm_;
	Snake_body snake;
	public static double score=0;
	boolean No_Food;
	Point2D a1,a2;
	Line2D line=new Line2D.Double();
	static double Screenx;
	static double Screeny;
	LinkedList<Snake_Point> body;
	private static double scalex=6,scaley=6;
	private int Next[][] =new int [][]{
			{-1,0},
			{0,1},
			{1,0},
			{0,-1}
			
	};
	static public double getScalex()
	{
		return scalex;
	}
	static public double getScaley()
	{
		return scaley;
	}
	static public void setScale(double scalex,double scaley)
	{
		if(scalex>0)
		{
			mainPanel.scalex=scalex;
		}
		if(scaley>0)
		{
			mainPanel.scaley=scaley;
		}
	}
	Snake_Point head;//蛇头
	static public int dirction;//方向
	mainPanel(Snake_body snake)//构造函数
	{
		this.setPreferredSize(new Dimension(5000,5000));
		this.body=snake.body;
		this.snake=snake;
		dirction=snake.dirction;
		a1=new Point2D.Double();
		a2 = new Point2D.Double();
		
		 
	}
	public void draw_Line(Graphics2D g2)//画线废弃了
	{
		Color t=g2.getColor();
		g2.setColor(Color.white);
		Rectangle2D Rect=new Rectangle2D.Double(this.getWidth()/scalex,this.getHeight()/scaley,
				this.getWidth()*(1-(2/scalex)),this.getHeight()*(1-(2/scaley)));
		g2.fill(Rect);
		g2.setColor(t);
		g2.setColor(Color.orange);
		for(int x=0;x<=MMap.get_x();x++)
		{
			line.setLine(this.getWidth()/scalex
					,x*Screeny+this.getHeight()/scaley
					, this.getSize().getWidth()
					-this.getSize().getWidth()/scalex, 
					x*Screeny+this.getSize().getHeight()/scaley);
			g2.draw(line);
		}
		for(int x=0;x<=MMap.get_y();x++)
		{
			line.setLine(this.getSize().getWidth()/scalex
					+x*Screenx,
					this.getSize().getHeight()/scaley,
					this.getSize().getWidth()/scalex+x*Screenx,
					this.getSize().getHeight()
					-this.getSize().getHeight()/scaley);
			g2.draw(line);
		}
	}
	public void draw_snake(Graphics2D g2)
	{
		
		
		Stroke k=g2.getStroke();
		
		double px,py;
		px=this.getSize().getWidth()/scalex;
		py=this.getSize().getHeight()/scaley;
		for(int i=1;i<body.size();i++)
		{
			if(i==1)
			{
				g2.setColor(new Color(128,0,0));
			}else if(i%2==0)
			{
				g2.setColor(new Color(154,205,50));
			}else 
			{
				g2.setColor(new Color(85,107,47));
			}
			a1.setLocation((double)body.get(i-1).x*Screenx+px+Screenx/2
					, (double)body.get(i-1).y*Screeny+Screeny/2+py);
			a2.setLocation((double)body.get(i).x*Screenx+px+Screenx/2
					,(double)body.get(i).y*Screeny+py+Screeny/2);
			g2.draw(new Line2D.Double(a1, a2));
		}
		g2.setStroke(k);//还原原来线段的粗细
		
	}
	public void move_snake(Graphics2D g2)
	{
		if(body.get(0).x+Next[dirction][0]<0||body.get(0).y+Next[dirction][1]<0||body.get(0).x+Next[dirction][0]>=MMap.get_x()||
		body.get(0).y+Next[dirction][1]>=MMap.get_y())
		{
			snake_died();
			return ;
		}
		body.addFirst(new Snake_Point(body.get(0).x+Next[dirction][0],body.get(0).y+Next[dirction][1]));
		for(int x=1;x<body.size();x++)
		{
			if(body.get(x).x==body.get(0).x&&body.get(x).y==body.get(0).y) 
			{
				snake_died();
				return ;
			}
			
		}
		if(MMap.attribute[body.get(0).x][body.get(0).y].value==0)
		{
			body.removeLast();
		}else 
		{
			Musics.eatSound();
			score+=MMap.attribute[body.get(0).x][body.get(0).y].value;
			MMap.attribute[body.get(0).x][body.get(0).y].value=0;
			if(MMap.attribute[body.get(0).x][body.get(0).y].type==Map_Type.Type.banana)
			{
				MMap.attribute[body.get(0).x][body.get(0).y].type=Map_Type.Type.empty;
				for(int x=0;x<5;x++) body.add(body.getLast());
			}else if(MMap.attribute[body.get(0).x][body.get(0).y].type==Map_Type.Type.apple)
			{
				if(body.size()>2) body.removeLast();
			}
			display_Score(g2);
			MMap.random_Food();
		}
	}
	public void set_wall(Graphics2D g2)
	{
		Rectangle2D Rect=new Rectangle2D.Double(0,0,Screenx,Screeny);
		BufferedImage wallfill=null;
		try {
			wallfill = ImageIO.read(new File("img\\wall.png"));
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		TexturePaint wall_=new TexturePaint(wallfill,Rect);
		g2.setPaint(wall_);
		g2.setStroke(new BasicStroke(10f));
		Rectangle2D wall=new Rectangle2D.Double(this.getWidth()/scalex,this.getHeight()/scaley,
				this.getWidth()*(1-(2/scalex)),this.getHeight()*(1-(2/scaley)));
		g2.draw(wall);
	}
	public void drawbackground(Graphics2D g2)//背景
	{
		g2.setColor(new Color(176,224,230));
		Rectangle2D rect=new Rectangle2D.Double(this.getWidth()/scalex,this.getHeight()/scaley,
				this.getWidth()*(1-(2/scalex)),this.getHeight()*(1-(2/scaley)));
		g2.fill(rect);
		
		
	}
	public synchronized void refresh(Graphics2D g2)
	{
		
		Rectangle2D Rect=new Rectangle2D.Double(0,0,Screenx,Screeny);
		tpapple=new TexturePaint(MMap.fillapple,Rect);
		tpbanana=new TexturePaint(MMap.fillbanana,Rect);
		tpwaterm_=new TexturePaint(MMap.fillwaterm_,Rect);
		for(int x=0;x<MMap.get_x();x++)
		{
			for(int y=0;y<MMap.get_y();y++)
			{
				if(MMap.attribute[x][y].value!=0)
				{
					Rectangle2D rect=new Rectangle2D.Double(this.getWidth()/scalex+Screenx*x,
							this.getHeight()/scaley+Screeny*y,Screenx,Screeny);
					if(MMap.attribute[x][y].type==Map_Type.Type.apple )g2.setPaint(tpapple);
					else if(MMap.attribute[x][y].type==Map_Type.Type.banana ) g2.setPaint(tpbanana);
					else if(MMap.attribute[x][y].type==Map_Type.Type.watermelon) g2.setPaint(tpwaterm_);
					g2.fill(rect);
				}
			}
		}
	}
	public synchronized void display_Score(Graphics2D g2)
	{
		g2.setColor(Color.BLACK);
		g2.drawString("分数:  "+score, (int)(this.getWidth()/scalex), (int)(this.getHeight()/scaley)-30);
		g2.drawString("长度:  "+body.size(),(int)(this.getWidth()/scalex),(int) (this.getHeight()/scaley)-10);
	}
	public void snake_died()
	{
		Musics.failSound();
		Key.Stop=true;
		snake.died=true;
		try {
			IO.in(score);
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		GameOver.getGameOver((int)chart.IO.set.first().longValue(),(int)score,Time.getManyTime());
		Time.setManyTime(0);
		mainPanel.score=0;
	}
	public void paintComponent(Graphics g)
	{
		game_lock.lock();
		try {
			Thread.sleep(20);
		} catch (InterruptedException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		Graphics2D g2=(Graphics2D)g;
		
		this.setDoubleBuffered(true);
		Screenx=(this.getWidth()*(1-(2/scalex)))/MMap.get_x();
		Screeny=(this.getHeight()*(1-(2/scaley)))/MMap.get_y();
		head=body.get(0);
		Image image=Toolkit.getDefaultToolkit().getImage("img\\wall2.png");
		g2.drawImage(image, 0, 0,this.getWidth(),this.getHeight(),this);//背景
		snake.dirction=dirction;//（保存蛇的方向。。。。）
		set_wall(g2);
		drawbackground(g2);
		refresh(g2);
		draw_snake(g2);
		display_Score(g2);
		if(No_Food==false)
		{
			MMap.random_Food();
			No_Food=true;
		}
		if(Key.Stop)
		{
			 return ;
		}
		
		move_snake(g2);
		g2.dispose();
		game_lock.unlock();
		this.repaint();
		
		}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO 自动生成的方法存根
		this.repaint();
	}
	@Override
	public void run() {
		// TODO 自动生成的方法存根
		this.repaint();
	}
	
	
	
}
